/**
 *   ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 *　　┃　　　┃神兽保佑
 *　　┃　　　┃代码无BUG！
 *　　┃　　　┗━━━┓
 *　　┃　　　　　　　┣┓
 *　    ┃　　　　　　　┏┛
 *　　┗┓┓┏━┳┓┏┛
 *　　　┃┫┫　┃┫┫
 *　　　┗┻┛　┗┻┛
**/
package com.asd.common.listener.reflex;

import com.asd.common.annotation.Aspect;
import com.asd.common.interceptors.bean.InvocationBean;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
 * 拦截器扫描
 *
 * @author zhanqi
 * @date 2020-03-07
 */
public class AspectReflex {
	// 扫描
	public void reflex(InvocationBean inv) {
		Set<Class<?>> classSet=new HashSet<>();
		Map<String, Class<?>> beanMap = BeanReflexMemory.of().getAllBean();
		beanMap.forEach((k,clazz)->{
			Aspect aspect = clazz.getAnnotation(Aspect.class);
			if (aspect == null) {
				return;
			}
			Method[] methods = clazz.getDeclaredMethods();
			if (methods == null) {
				return;
			}
			classSet.add(clazz);
		});
		TreeSet<Class<?>> newClassSet = getSort(classSet);
		newClassSet.forEach(clazz->{
			Method[] methods = clazz.getDeclaredMethods();
			if (methods == null) {
				return;
			}
			invoke(clazz,methods,inv);
		});
	}

	private void invoke(Class<?> clazz,Method[] methods, InvocationBean inv) {
		for (Method method : methods) {
			if (method.getName().equals("exe")) {
				try {
					Object aop = new AutowiredReflex().autowired(clazz, clazz.newInstance());
					method.invoke(aop, inv);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}
	}

	//set排序
	private TreeSet<Class<?>> getSort(Set<Class<?>> classSet) {
		TreeSet<Class<?>> sortSet = new TreeSet<Class<?>>((c1, c2) -> {
			Aspect Aspect1= c1.getAnnotation(Aspect.class);
			Aspect Aspect2 = c2.getAnnotation(Aspect.class);
			Integer AspectValue1 = Aspect1.value();
			Integer AspectValue2= Aspect2.value();
			return AspectValue1.compareTo(AspectValue2);//正序

		});
		sortSet.addAll(classSet);
		return sortSet;
	}
}
